#pragma once
#include "CFrameworkElement.h"
#include "CRasterizerEdgeStore.h"

class CSolidColorBrush;
class CPlainPen;
class CImageBrush;
class HitTestPolygon;
class CDoubleCollection;



class CShape :
	public CFrameworkElement
{

protected: 
	CShape(CCoreServices * pCore);
protected: 
	virtual ~CShape();
public: 
	static HRESULT Create(CDependencyObject * * ppObject, CREATEPARAMETERS * pCreate);
	virtual XUINT32 GetTypeIndex() const;
	virtual HRESULT GetBoundingRectangle(struct XRECTF_WH * pRect);
	virtual HRESULT SetValue(CDependencyProperty * pdp, CValue * pValue);
	virtual HRESULT UpdateRenderGeometry();
	virtual HRESULT UpdateRasterizerPath();
	virtual void GetIndependentlyAnimatedBrushes(CSolidColorBrush * * ppFillBrush, CSolidColorBrush * * ppStrokeBrush);
	static HRESULT GetShapeGeometryTransform(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * pArgs, CValue * pResult);
	CGeometry * GetRenderGeometry();
	virtual HRESULT NWRenderPreChildrenEdgesVirtual(const struct SharedRenderParams & sharedRP, const struct NWRenderParams & nwRP, xvector<xref_ptr<CRasterizerEdgeStore> > & vecEdgeStores);
	static void NWSetFillBrushDirty(CDependencyObject * pTarget, enum DirtyFlags::Value flags);
	static void NWSetStrokeBrushDirty(CDependencyObject * pTarget, enum DirtyFlags::Value flags);
	static void UpdateRectangleBoundsForStretchMode(enum XcpBrushStretch stretchMode, struct XRECTF_WH & rectBounds);
protected: 
	HRESULT InitPenFromShape(CPlainPen * pPen);
	virtual HRESULT MeasureOverride(struct XSIZEF availableSize, struct XSIZEF & desiredSize);
	virtual HRESULT ArrangeOverride(struct XSIZEF finalSize, struct XSIZEF & newFinalSize);
	virtual XINT32 NeedsSmoothJoin();
	void ReplaceRenderGeometry(CGeometry * pRender);
	XFLOAT GetStrokeThickness();
	virtual void EnsureContentRenderDataVirtual(enum RenderWalkType oldType, enum RenderWalkType newType);
	virtual HRESULT GetBoundsForImageBrushVirtual(const CImageBrush * pImageBrush, struct XRECTF_WH * pBounds);
public: 
	virtual XBOOL NWIsContentDirty();
	virtual XBOOL IsMaskDirty(HWShapeRealization * pHwShapeRealization);
protected: 
	virtual XBOOL NWCanApplyOpacityWithoutLayer();
	virtual void NWCleanDirtyFlags();
	struct XRECTF_WH GetOutlineRect(XBOOL fCheckDegenerateStroke);
private: 
	HRESULT GetStretchTransform(CMILMatrix * pMatrix);
	HRESULT GenerateEdgesCommon(CFrameVectorBuffer * pVectorBuffer, const CMILMatrix * pRenderTransform, XBOOL fTransformChanged, XBOOL fGeometryChanged, XBOOL fFillBrushChanged, XBOOL fStrokeBrushChanged, XFLOAT rOpacity, CLayer * pTargetLayer, xvector<xref_ptr<CRasterizerEdgeStore> > & vecEdgeStores);
public: 
	CBrush * m_pFill;
	CBrush * m_pStroke;
	enum XcpPenCap m_capStartLine;
	enum XcpPenCap m_capEndLine;
	enum XcpLineJoin m_penLineJoin;
	enum XcpPenCap m_capStrokeDash;
	XFLOAT m_rStrokeDashOffset;
	XFLOAT m_rStrokeMiterLimit;
	XFLOAT m_rStrokeThickness;
	CDoubleCollection * m_pStrokeDashArray;
	enum XcpBrushStretch m_Stretch;
private: 
	XBOOL m_fIsInsideFrame;
	XBOOL m_fIsDefaultWidth:1;
	XBOOL m_fIsDefaultHeight:1;
	struct AcceleratedBrushParams * m_pPALFillBrushParams;
	struct AcceleratedBrushParams * m_pPALStrokeBrushParams;
protected: 
	XBOOL m_fFillBrushDirty:1;
	XBOOL m_fStrokeBrushDirty:1;
	CGeometry * m_pRender;
	virtual XBOOL CanStretchGeometry();
	virtual HRESULT D2DPreChildrenRenderVirtual(const struct SharedRenderParams & sharedRP, const struct D2DRenderParams & d2dRP);
	virtual HRESULT D2DHitTestSelf(struct XPOINTF ptHit, CUIElement * * ppResult);
	virtual HRESULT D2DComputeInnerBounds(struct XRECTF_RB * pInnerBounds);
	virtual HRESULT D2DEnsureResources(const struct D2DPrecomputeParams & cp, const CMILMatrix * pMyAccumulatedTransform);
private: 
	HRESULT CreateStrokeStyle(struct IPALAcceleratedGraphicsFactory * pD2DFactory, struct IPALStrokeStyle * * ppStrokeStyle);
	XBOOL ShouldRender(XBOOL * pHasElementBounds, struct XRECTF_WH * pElementBounds);
protected: 
	virtual HRESULT PreChildrenPrintVirtual(const struct SharedRenderParams & sharedPrintParams, const struct D2DPrecomputeParams & cp, const struct D2DRenderParams & printParams);
public: 
	static void NWSetGeometryDirty(CDependencyObject * pTarget, enum DirtyFlags::Value flags);
	HRESULT GetFillBounds(struct XRECTF_RB * pBounds);
	HRESULT GetStrokeBounds(struct XRECTF_RB * pBounds);
protected: 
	virtual HRESULT GenerateContentBounds(struct XRECTF_RB * pBounds);
	virtual HRESULT HitTestLocalInternal(const HitTestPolygon & target, XBOOL * pHit);
	virtual HRESULT HitTestLocalInternal(const struct XPOINTF & target, XBOOL * pHit);
	HRESULT GetGeometryBounds(struct XRECTF_RB * pBounds);
	HRESULT GetWidenedGeometryBounds(struct XRECTF_RB * pBounds);
	void InvalidateGeometryBounds();
private: 
	XBOOL m_geometryBoundsDirty:1;
	XBOOL m_geometryWidenedBoundsDirty:1;
	struct XRECTF_RB m_geometryBounds;
	struct XRECTF_RB m_geometryWidenedBounds;
	struct XRECTF_RB m_innerFillBounds;
	struct XRECTF_RB m_innerStrokeBounds;
	static HRESULT ApplyContentStretch(XFLOAT strokeThickness, enum XcpBrushStretch stretchMode, const struct XRECTF_RB & geometryNaturalBounds, const struct XSIZEF & renderConstraintBounds, struct XSIZEF * pStretchedBounds);
	HRESULT GenerateGeometryBounds(const struct XSIZEF * pConstraintBounds, enum XcpBrushStretch stretchMode, struct XRECTF_RB * pBounds);
protected: 
	struct IPALStrokeStyle * m_pStrokeStyle;
	struct IPALAcceleratedGeometry * m_pElementBoundsClip;
};

